using System;
using System.Collections;
using System.Collections.Generic;
using System.IO.Compression;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Security.Permissions;

namespace OracleInternal.Common
{
	[Serializable]
	internal class OracleTimeZone : ISerializable
	{
		private static OracleTimeZone tzCacheObj;

		private const string FILENAME = "TimeZone.dst";

		internal int m_latestTimeZoneVersion = 26;

		internal const int INV_ZONEID = -1;

		internal Dictionary<int, string> m_zoneIdMap;

		internal Hashtable m_zoneIdToOffsetMap;

		[SecurityPermission(SecurityAction.Assert, SerializationFormatter = true)]
		public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
		{
			info.AddValue("ZoneIdMap", m_zoneIdMap);
			info.AddValue("zoneIdToOffsetMap", m_zoneIdToOffsetMap);
			info.AddValue("latestTZversion", m_latestTimeZoneVersion);
		}

		internal OracleTimeZone()
		{
		}

		[SecurityPermission(SecurityAction.Assert, SerializationFormatter = true)]
		public OracleTimeZone(SerializationInfo info, StreamingContext context)
		{
			m_zoneIdMap = (Dictionary<int, string>)info.GetValue("ZoneIdMap", typeof(Dictionary<int, string>));
			m_zoneIdToOffsetMap = (Hashtable)info.GetValue("zoneIdToOffsetMap", typeof(Hashtable));
			m_latestTimeZoneVersion = (int)info.GetValue("latestTZversion", typeof(int));
		}

		[SecurityPermission(SecurityAction.Assert, SerializationFormatter = true)]
		internal static OracleTimeZone GetInstance()
		{
			try
			{
				if (tzCacheObj == null)
				{
					tzCacheObj = new TimeZoneFileReader().ReadObj();
				}
			}
			catch (Exception ex)
			{
				throw ex;
			}
			return tzCacheObj;
		}

		internal int GetZoneId(string zoneName)
		{
			IDictionaryEnumerator dictionaryEnumerator = m_zoneIdMap.GetEnumerator();
			while (dictionaryEnumerator.MoveNext())
			{
				if ((string)dictionaryEnumerator.Value == zoneName)
				{
					return (int)dictionaryEnumerator.Key;
				}
			}
			return -1;
		}

		internal string GetZoneName(int id)
		{
			return m_zoneIdMap[id];
		}

		internal int GetlatestTZversion()
		{
			return m_latestTimeZoneVersion;
		}

		internal void GetOffsetOfUTCTime(DateTime? utcTime, int zoneid, out TimeSpan offset, out bool isDST)
		{
			ZoneValue zoneValue = (ZoneValue)m_zoneIdToOffsetMap[zoneid];
			Transitions transitions = zoneValue.m_transitions[0];
			if (utcTime.HasValue)
			{
				for (int i = 0; i < zoneValue.m_transitions.Length; i++)
				{
					Transitions transitions2 = zoneValue.m_transitions[i];
					int num = DateTime.Compare(utcTime.Value, transitions2.m_dateTimeInUtc);
					if (num < 0)
					{
						break;
					}
					transitions = transitions2;
					if (num == 0)
					{
						break;
					}
				}
			}
			offset = transitions.m_hourOffset;
			isDST = ((transitions.m_dst > 0) ? true : false);
		}

		internal bool GetOffsetOfLocalTime(DateTime? localTime, int zoneid, out TimeSpan offset, out bool isDST)
		{
			ZoneValue zoneValue = (ZoneValue)m_zoneIdToOffsetMap[zoneid];
			Transitions transitions = zoneValue.m_transitions[0];
			if (localTime.HasValue)
			{
				for (int i = 0; i < zoneValue.m_transitions.Length; i++)
				{
					Transitions transitions2 = zoneValue.m_transitions[i];
					int num = DateTime.Compare(localTime.Value, transitions2.m_dateTimeInLocal);
					if (num < 0)
					{
						break;
					}
					transitions = transitions2;
					if (num == 0)
					{
						break;
					}
				}
			}
			offset = transitions.m_hourOffset;
			isDST = ((transitions.m_dst > 0) ? true : false);
			if (isDST && (localTime == transitions.m_dateTimeInLocal || localTime < transitions.m_dateTimeInLocal.Add(transitions.m_dstDuration)))
			{
				return false;
			}
			return true;
		}

		internal bool IsValidZoneId(int id)
		{
			return m_zoneIdMap.ContainsKey(id);
		}

		internal bool IsValidZoneName(string zoneName)
		{
			return m_zoneIdMap.ContainsValue(zoneName);
		}

		[SecurityPermission(SecurityAction.Assert, Unrestricted = true)]
		internal static object ReadObj(string entryName)
		{
			object obj = null;
			using GZipStream serializationStream = new GZipStream(Assembly.GetExecutingAssembly().GetManifestResourceStream("OracleInternal.I18N." + entryName), CompressionMode.Decompress, leaveOpen: true);
			return new BinaryFormatter
			{
				Binder = new DeserializationBinder0()
			}.Deserialize(serializationStream);
		}

		internal void SetZoneIdMap(Dictionary<int, string> zoneIdMap)
		{
			m_zoneIdMap = zoneIdMap;
		}

		internal void SetLatestTZVersion(int latestTZVersion)
		{
			m_latestTimeZoneVersion = latestTZVersion;
		}

		internal void SetZoneIdtoOffsetMap(Hashtable offsetMap)
		{
			m_zoneIdToOffsetMap = offsetMap;
		}
	}
}
